package com.niit.mall.product.controller;


import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.niit.mall.api.domain.dto.OrderDetailDTO;
import com.niit.mall.common.api.CommonResult;
import com.niit.mall.common.api.IErrorCode;
import com.niit.mall.common.domain.dto.PageDTO;
import com.niit.mall.common.utils.BeanUtils;
import com.niit.mall.common.utils.UserContext;
import com.niit.mall.product.domain.dto.IndexProductDTO;
import com.niit.mall.product.domain.dto.ProductDTO;
import com.niit.mall.product.domain.dto.StockDTO;
import com.niit.mall.product.domain.po.*;
import com.niit.mall.product.domain.query.BrandQuery;
import com.niit.mall.product.domain.query.ProductQuery;
import com.niit.mall.product.domain.query.ProductSearch;
import com.niit.mall.product.domain.vo.*;
import com.niit.mall.product.service.*;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Update;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 商品服务
 *
 * @module pardo_mall
 * @BelongsProject: pardo_mall_backend
 * @BelongsPackage: com.niit.mall.product.controller
 * @Author: XihenXi
 * @CreateTime: 2025-06-8  18:49
 * @Description: 商品请求控制器
 * @Version: 1.0
 */

@Slf4j
@RestController
@RequestMapping("/product")
@RequiredArgsConstructor
public class ProductController {

    private final IProductService productService;
    private final IAdvertiseService advertiseService;
    private final ICategoryService categoryService;
    private final IBrandService brandService;
    private final ICouponService couponService;
    private final IUserCouponService userCouponService;

    /**
     * 获取商品分页和品牌、分类列表
     *
     * @return 封装了商品、品牌、分类信息的对象
     */
    @GetMapping("/fullList")
    public CommonResult<ProductSynthesisVO> queryProductAndBrandAndCategoryList(ProductQuery query) {
        ProductSynthesisVO productSynthesisVOList = productService.queryProductAndBrandAndCategoryList(query);
        return CommonResult.success(productSynthesisVOList);
    }

    /**
     * 分页查询商品信息
     *
     * @param query 商品查询条件
     * @return 返回通用结果对象，包含分页查询到的商品信息
     */
    @GetMapping("/page")
    public CommonResult<PageDTO<ProductDTO>> queryProductByPage(ProductQuery query) {
        PageDTO<ProductDTO> productVOList = productService.queryProductByPage(query);
        return CommonResult.success(productVOList);
    }

    /**
     * 分页获取品牌信息
     * @param query 查询条件
     * @return 返回通用结果对象，包含更新后的库存信息
     */
    @GetMapping("/brand/page")
    public CommonResult<PageDTO<BrandVO>> queryBrandByPage(BrandQuery query) {
        PageDTO<BrandVO> brandVOList = brandService.queryBrandByPage(query);
        return CommonResult.success(brandVOList);
    }

    /**
     * 更新库存信息的方法
     *
     * @param stockDTO 包含库存更新信息的DTO对象
     * @return 返回更新操作的结果，如果成功返回相应的状态和信息，失败则返回错误信息
     */
    @PutMapping("/stock")
    public CommonResult updateStock(@RequestBody StockDTO stockDTO) {
        boolean result = productService.updateStock(stockDTO);
        //  TODO 添加库存更新逻辑
        return null;
    }

    /**
     * 扣减库存方法
     *
     * @param items 订单详情数据传输对象列表
     */
    @PutMapping("/stock/deduct")
    public void deductStock(@RequestBody List<OrderDetailDTO> items) {
        productService.deductStock(items);
    }
    @PutMapping("/stock/reduce")
    public CommonResult reduceStock(@RequestBody Map<Long, Integer> productIdToQuantityMap) {

        Map<Long, String> result = new HashMap<>();
        // 查询所有相关商品
        List<Product> productList = productService.list(
            new LambdaQueryWrapper<Product>().in(Product::getId, productIdToQuantityMap.keySet())
        );
        log.info("查询到的商品列表：{}", productList);

        // 遍历商品列表，减少库存
        for (Product product : productList) {
            Integer quantity = productIdToQuantityMap.get(product.getId());
            if (quantity > product.getStock()) {
                result.put(product.getId(), "库存不足");
                continue;
            }
            product.setStock(product.getStock() - quantity);
            productService.updateById(product);
        }

        return CommonResult.success(null);
    }

    /**
     * 根据ID删除项目
     *
     * @param id 项目ID
     */
    @DeleteMapping("{id}")
    public void deleteItemById(@PathVariable("id") Long id) {
        productService.removeById(id);
    }

    /**
     * 根据ID设置删除属性
     *
     * @param id 项目ID
     */
    @PutMapping("/delete/{id}")
    public CommonResult deleteItem(@PathVariable("id") Long id) {
        LambdaUpdateWrapper<Product> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper
                .eq(Product::getId, id)
                .set(Product::getIsDeleted, 1);
        productService.update(updateWrapper);
        return CommonResult.success("已设置删除标记为1");
    }

    /**
     * 根据ID列表查询商品信息
     *
     * @param ids 商品ID列表
     * @return 商品数据传输对象列表
     */
    @GetMapping
    public List<ProductDTO> queryItemByIds(@RequestParam("ids") List<Long> ids) {
        return productService.queryItemByIds(ids);
    }

    /**
     * 根据ID查询商品信息的方法
     *
     * @param id 商品ID
     * @return 返回封装了商品视图对象的通用结果
     */
    @GetMapping("{id}")
    public CommonResult<ProductVO> queryItemById(@PathVariable("id") Long id) {
        Product product = productService.getById(id);
        ProductVO productVO = BeanUtils.copyBean(product, ProductVO.class);
        return CommonResult.success(productVO);
    }

    /**
     * 根据ID查询商品信息DTO的方法
     * @param id 商品ID
     * @return 返回封装了商品DTO视图对象的通用结果
     */
    @GetMapping("/dto/{id}")
    public CommonResult<ProductDTO> queryItemDTOById(@PathVariable("id") Long id) {
        Product product = productService.getById(id);
        ProductDTO productDTO = BeanUtils.copyBean(product, ProductDTO.class);
        return CommonResult.success(productDTO);
    }


    /**
     * 根据多个ID查询产品信息的方法。
     *
     * @param ids 逗号分隔的商品ID字符串
     * @return 包含多个产品视图对象（ProductVO）的列表。
     */
    @GetMapping("/vo")
    public List<ProductVO> queryItemByIdsVO(@RequestParam("ids")  List<Long> ids) {
        List<Product> productList = productService.list(new LambdaQueryWrapper<Product>()
               .in(Product::getId, ids));
        List<ProductVO> productVOList = BeanUtils.copyToList(productList, ProductVO.class);
        return productVOList;
    }

    /**
     * 通过ID查询商品信息VO（包括逻辑删除）
     *
     * @param id 商品ID
     * @return 封装了商品视图对象的通用结果
     */
    @GetMapping("/logic/{id}")
    public CommonResult<ProductDTO> queryByIdLogic(@PathVariable("id") Long id) {
        ProductDTO productDTO = productService.queryByIdLogic(id);
        log.info("查询商品信息：{}", productDTO);
        return CommonResult.success(productDTO);
    }

    /**
     * 保存商品信息
     *
     * @param item 商品数据传输对象（DTO）
     */
    @PostMapping
    public void saveItem(@RequestBody ProductDTO item) {
        productService.save(BeanUtils.copyBean(item, Product.class));
    }

    /**
     * 更新商品状态的方法
     *
     * @param id            商品ID
     * @param publishStatus 要更新的商品状态
     */
    @PutMapping("/status/{id}/{publishStatus}")
    public void updateItemStatus(@PathVariable("id") Long id, @PathVariable("publishStatus") Integer publishStatus) {
        Product item = new Product();
        item.setId(id);
        item.setPublishStatus(publishStatus);
        productService.updateById(item);
    }

    /**
     * 更新商品信息的方法
     *
     * @param item 商品数据传输对象
     */
    @PutMapping
    public void updateItem(@RequestBody ProductDTO item) {
        log.info("更新商品信息：{}", item);
        // 不允许修改商品状态，所以强制设置为null，更新时，就会忽略该字段
        //item.setStatus(null);
        item.setUpdateDate(LocalDate.now());
        // 更新
        productService.updateById(BeanUtils.copyBean(item, Product.class));
    }

    /**
     * 查询广告信息的方法
     *
     * @return 返回包含广告信息的CommonResult对象，其中包含转换后的AdvertiseVO列表
     */
    @GetMapping("/ad")
    public CommonResult<List<AdvertiseVO>> queryAd() {
        List<Advertise> advertiseList = advertiseService.list();
        // PO转VO
        List<AdvertiseVO> advertiseVOList = BeanUtil.copyToList(advertiseList, AdvertiseVO.class);
        return CommonResult.success(advertiseVOList);
    }

    /**
     * 获取品牌列表VO的方法
     *
     * @return 封装了品牌列表的CommonResult对象
     */
    @GetMapping("/brand_vo")
    public CommonResult<List<BrandVO>> queryBrandVO() {
        return CommonResult.success(brandService.queryBrandVO());
    }

    /**
     * 获取分类列表VO的方法
     *
     * @return 封装了分类列表的CommonResult对象
     */
    @GetMapping("/category_vo")
    public CommonResult<List<CategoryVO>> queryCategoryVO() {
        return CommonResult.success(categoryService.queryCategoryVO());
    }

    /**
     * 获取分类列表的方法
     *
     * @return 封装了分类列表的CommonResult对象
     */
    @GetMapping("/category")
    public CommonResult<List<Category>> queryCategory() {
        List<Category> list = categoryService.list();
        log.info("查询分类列表：{}", list);
        return CommonResult.success(list);
    }

    /**
     * 根据id获取分类信息
     *
     * @param id 分类id
     * @return 封装了分类信息的通用结果对象
     */
    @GetMapping("/category/{id}")
    public CommonResult<Category> queryCategoryById(@PathVariable Integer id) {
        return CommonResult.success(categoryService.getById(id));
    }

    /**
     * 根据id修改分类信息
     *
     * @param category 分类信息
     * @return 操作结果
     */
    @PutMapping("/category")
    public CommonResult updateCategory(@RequestBody Category category) {
        category.setUpdateDate(LocalDate.now());
        boolean result = categoryService.updateById(category);
        return result ? CommonResult.success(null) : CommonResult.failed();
    }

    /**
     * 添加分类信息
     *
     * @param category 分类信息
     * @return 添加结果
     */
    @PostMapping("/category")
    public CommonResult<Category> addCategory(@RequestBody Category category) {
        category.setCreateDate(LocalDate.now());
        category.setUpdateDate(LocalDate.now());
        boolean result = categoryService.save(category);
        return result ? CommonResult.success(category) : CommonResult.failed();
    }

    /**
     * 逻辑删除分类信息
     *
     * @param id 品牌ID
     * @return 操作结果
     */
    @PutMapping("/category/logic/{id}")
    public CommonResult<String> deleteCategory(@PathVariable Integer id) {
        boolean result = categoryService.removeById(id);
        return result ? CommonResult.success("删除成功") : CommonResult.success("删除失败");
    }

    /**
     * 根据id获取品牌信息
     *
     * @param id 品牌id
     * @return 封装了品牌信息的通用结果对象
     */
    @GetMapping("/brand/{id}")
    public CommonResult<Brand> queryBrandById(@PathVariable("id") Long id) {
        return CommonResult.success(brandService.getById(id));
    }

    /**
     * 根据id修改品牌信息
     *
     * @param brand 品牌信息
     * @return 操作结果
     */
    @PutMapping("/brand")
    public CommonResult updateBrand(@RequestBody Brand brand) {
        brand.setUpdateDate(LocalDate.now());
        boolean result = brandService.updateById(brand);
        return result ? CommonResult.success(null) : CommonResult.failed();
    }

    /**
     * 添加品牌信息
     *
     * @param brand 品牌信息
     * @return 添加结果
     */
    @PostMapping("/brand")
    public CommonResult<Brand> addBrand(@RequestBody Brand brand) {
        brand.setCreateDate(LocalDate.now());
        brand.setUpdateDate(LocalDate.now());
        boolean result = brandService.save(brand);
        return result ? CommonResult.success(brand) : CommonResult.failed();
    }

    /**
     * 逻辑删除品牌信息
     *
     * @param id 品牌ID
     * @return 操作结果
     */
    @PutMapping("/brand/logic/{id}")
    public CommonResult<String> deleteBrand(@PathVariable Integer id) {
        boolean result = brandService.removeById(id);
        return result ? CommonResult.success("删除成功") : CommonResult.success("删除失败");
    }


    /**
     * 查询首页产品列表的方法
     *
     * @param type   查询类型，0表示猜你喜欢，1表示热销商品，2表示新品上市
     * @param isHome 是否为首页查询，true返回10条，false返回全部
     * @return 返回包含产品视图对象列表的通用结果
     */
    @GetMapping("/home/{type}/{isHome}")
    public CommonResult<List<ProductVO>> queryHomeProduct(@PathVariable Integer type, @PathVariable Boolean isHome) {
        // 0 - 猜你喜欢 1 - 热销商品 2 - 新品上市
        List<Product> productList;
        if (type == 0) {
            // 随机获取商品
            productList = productService.lambdaQuery()
                    .eq(Product::getPublishStatus, 1)
                    .eq(Product::getVerifyStatus, 1)
                    .list();
            // 随机排序
            Collections.shuffle(productList);
        } else if (type == 1) {
            // 查询销量排行商品
            productList = productService.lambdaQuery()
                    .eq(Product::getPublishStatus, 1)
                    .eq(Product::getVerifyStatus, 1)
                    .orderByDesc(Product::getSold)
                    .list();
        } else if (type == 2) {
            // 查询创建时间最新的商品
            productList = productService.lambdaQuery()
                    .eq(Product::getPublishStatus, 1)
                    .eq(Product::getVerifyStatus, 1)
                    .orderByDesc(Product::getCreateDate)
                    .list();
        } else {
            return CommonResult.failed("无效的类型参数");
        }

        // 根据 isHome 决定是否限制数量
        if (isHome) {
            int limit = Math.min(10, productList.size());
            productList = productList.subList(0, limit);
        }

        List<ProductVO> productVOList = BeanUtils.copyToList(productList, ProductVO.class);
        return CommonResult.success(productVOList);
    }


    /**
     * 根据商品ID查询相关分类并返回同分类商品
     *
     * @param id 商品ID
     * @return 同分类的其他商品列表
     */
    @GetMapping("/related/{id}")
    public CommonResult<List<ProductVO>> queryRelatedProduct(@PathVariable("id") Long id) {
        // 1. 查询当前商品信息
        Product currentProduct = productService.getById(id);
        if (currentProduct == null) {
            return CommonResult.failed("商品不存在");
        }

        // 2. 获取商品所属分类ID
        Long categoryId = currentProduct.getCategoryId();
        if (categoryId == null) {
            return CommonResult.failed("商品未关联分类");
        }

        // 3. 查询该分类下的所有商品（排除当前商品），并筛选已上架、已审核的
        List<Product> relatedProducts = productService.lambdaQuery()
                .eq(Product::getCategoryId, categoryId)
                .ne(Product::getId, id)
                .eq(Product::getPublishStatus, 1)
                .eq(Product::getVerifyStatus, 1)
                .list();

        // 4. 随机取最多10个商品作为推荐
        Collections.shuffle(relatedProducts);
        int limit = Math.min(10, relatedProducts.size());
        if (limit > 0) {
            relatedProducts = relatedProducts.subList(0, limit);
        }

        // 5. 转换为 VO 并返回结果
        List<ProductVO> productVOList = BeanUtils.copyToList(relatedProducts, ProductVO.class);
        return CommonResult.success(productVOList);
    }


    /**
     * 查询父级分类信息
     *
     * @return 返回包含父级分类视图对象的通用结果
     */
    @GetMapping("/parent")
    public CommonResult<List<CategoryVO>> queryParentCategory() {
        List<Category> categoryList = categoryService.lambdaQuery()
                .eq(Category::getLevel, 0)
                .list();
        List<CategoryVO> categoryVOList = BeanUtils.copyToList(categoryList, CategoryVO.class);
        return CommonResult.success(categoryVOList);
    }

    /**
     * 根据父级分类ID查询子级分类的所有商品
     *
     * @param id 父级分类ID
     * @return 子分类下的商品列表（VO形式）
     */
    @GetMapping("/child/{id}")
    public CommonResult<List<ProductVO>> queryProductByParentCategoryId(@PathVariable Integer id) {
        // 1. 查询所有子分类
        List<Category> subCategories = categoryService.lambdaQuery()
                .eq(Category::getParentId, id)
                .list();

        if (subCategories == null || subCategories.isEmpty()) {
            return CommonResult.success(Collections.emptyList());
        }

        // 2. 提取子分类ID列表
        List<Long> categoryIds = subCategories.stream()
                .map(Category::getId)
                .collect(Collectors.toList());

        // 3. 查询这些子分类下的所有商品，并筛选已上架、已审核的商品
        List<Product> products = productService.lambdaQuery()
                .in(Product::getCategoryId, categoryIds)
                .eq(Product::getPublishStatus, 1)
                .eq(Product::getVerifyStatus, 1)
                .list();

        // 4. 转换为 VO 并返回结果
        List<ProductVO> productVOList = BeanUtils.copyToList(products, ProductVO.class);
        return CommonResult.success(productVOList);
    }


    /**
     * 根据ID查询规格信息的方法
     *
     * @param id 指定的ID
     * @return 返回包含规格信息的通用结果对象
     */
    @GetMapping("/spec/{id}")
    public CommonResult<Map<String, List<String>>> querySpecsById(@PathVariable("id") Long id) {
        return CommonResult.success(productService.querySpecsById(id));
    }


    /**
     * 获取优惠券数量的接口
     *
     * @return 返回一个包含优惠券数量的CommonResult对象
     */
    @GetMapping("/coupon/count/{userId}")
    public Long getCouponNum(@PathVariable("userId") Long userId){
        // 根据 用户ID 查询优惠券数量
        Long couponNum = userCouponService.count(
                new LambdaUpdateWrapper<UserCoupon>()
                        .eq(UserCoupon::getUserId, userId.toString())
        );
        return couponNum;
    }



    @GetMapping("/search")
    public CommonResult<PageDTO<ProductVO>> searchProduct(ProductSearch productSearch) {
        log.info("搜索商品：{}", productSearch);
        PageDTO<ProductVO> productVOList = productService.searchProductByPage(productSearch);
        return CommonResult.success(productVOList);
    }

    // 用户领取优惠券 TODO: 待实现
    // 用户收藏商品 TODO: 待实现
    // 查询用户收藏的商品 TODO: 待实现
    // 商品评价 TODO: 待实现
    // 用户浏览历史 TODO: 待实现
    // 查询用户浏览历史 TODO: 待实现
    // 热门商品 TODO: 待实现

}
